<?php

namespace Biz\Services\Passport;

use Biz\Models\User\User;
use Biz\Models\Passport\Client;
use Illuminate\Support\Facades\Cache;
use Biz\Constants\OAuth\OAuthConstants;
use Biz\Constants\OAuth\ScopeConstants;
use Laravel\Passport\PersonalAccessTokenResult;
use Biz\Repositories\Passport\AccessTokenRepository;

/**
 * TokenRepository.
 *
 * @license [http://www.85do.com] [杭州永奥网络科技有限公司]
 * @copyright Copyright (c) 2018-2026 Hangzhou Yongao Technology Co., Ltd. All rights reserved.
 */
class AccessTokenService
{
    /**
     * 个人Token 缓存Key.
     *
     * @var string
     */
    private $UserPersonalAccessTokenCacheKey = 'User.Personal.AccessToken:%s';
    /**
     * @var \Lumen\Repository\Contracts\RepositoryContract
     */
    protected $repository;

    /**
     * @var ClientService
     */
    protected $clientService;

    /**
     * RepositoryController constructor.
     *
     * @param AccessTokenRepository $repository
     * @param ClientService         $clientService
     */
    public function __construct(AccessTokenRepository $repository, ClientService $clientService)
    {
        $this->repository         = $repository;
        $this->clientService      = $clientService;
    }

    /**
     * 处理APP获取Token的请求参数.
     *
     * @param Client $oauthClient
     *
     * @return mixed
     */
    public function handleAppTokenRequestParameters(Client $oauthClient)
    {
        // OAuth params
        //$data['user_id']       = $oauthClient->user_id;// 注意此模式不需要传递，只有在密码模式时必传
        $data['grant_type']    = OAuthConstants::GRANT_TYPE_CLIENT_CREDENTIALS;
        $data['client_id']     = $oauthClient->id;
        $data['client_secret'] = $oauthClient->secret;
        $data['scope']         = sprintf('%s', ScopeConstants::SCOPE_APP_SITE); // 空格隔开

        return $data;
    }

    /**
     * 获取缓存中的AccessToken.
     *
     * @param User $user
     *
     * @return PersonalAccessTokenResult
     */
    public function getPersonalAccessToken(User $user): PersonalAccessTokenResult
    {
        $cacheKey = sprintf($this->UserPersonalAccessTokenCacheKey, $user->id);
        /** @var PersonalAccessTokenResult $personalAccessTokenResult */
        $personalAccessTokenResult = Cache::rememberForever($cacheKey, function () use ($user) {
            $scopes = [
                ScopeConstants::SCOPE_USER,
            ];
            $name = sprintf('Personal Access Token For User-%s', $user->id);

            if ($user->isClient()) {
                $scopes = [
                    ScopeConstants::SCOPE_USER_CLIENT,
                    ScopeConstants::SCOPE_APP_SITE,
                ];
                $name = sprintf('Personal Access Token For UserClient-%s', $user->id);
            } elseif ($user->isMember()) {
                $scopes = [
                    ScopeConstants::SCOPE_USER_MEMBER,
                    ScopeConstants::SCOPE_APP_SITE,
                ];
                $name = sprintf('Personal Access Token For UserMember-%s', $user->id);
            }

            return $user->createToken($name, $scopes);
        });

        return $personalAccessTokenResult;
    }

    /**
     * 获取缓存中的AccessToken.
     *
     * @param User $user
     *
     * @return mixed
     */
    public function removePersonalAccessToken(User $user): bool
    {
        /** @var PersonalAccessTokenResult $personalAccessTokenResult */
        $personalAccessTokenResult = $this->getPersonalAccessToken($user);
        if ($personalAccessTokenResult) {
            $accessToken = $personalAccessTokenResult->token;
            //$accessToken->update(['revoked' => true]);
            $accessToken->delete();

            $cacheKey = sprintf($this->UserPersonalAccessTokenCacheKey, $user->id);
            Cache::forget($cacheKey);
        }

        return true;
    }
}
